package com.example.rabc.config;

import com.example.rabc.entity.User;
import com.example.rabc.service.UserService;
import com.example.rabc.service.PermissionService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Arrays;
import java.util.List;

/**
 * 权限拦截器，用于检查用户是否有访问当前请求的权限
 */
@Component
public class PermissionInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    @Autowired
    private PermissionService permissionService;


    // 白名单路径，不需要权限验证
    private static final List<String> WHITE_LIST = Arrays.asList(
            "/api/auth/login",
            "/api/auth/register",
            "/api/users/register",
            "/error"
    );

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        String requestURI = request.getRequestURI();

        // 检查是否在白名单中
        if (WHITE_LIST.stream().anyMatch(requestURI::contains)) {
            return true;
        }

        // 检查是否有@PermissionRequired注解
        String requiredPermission = null;
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            PermissionRequired permissionRequired = handlerMethod.getMethodAnnotation(PermissionRequired.class);
            if (permissionRequired != null) {
                requiredPermission = permissionRequired.value();
            }
        }

        // 如果没有注解，则从请求头获取权限码
        if (requiredPermission == null || requiredPermission.isEmpty()) {
            requiredPermission = getRequiredPermission(request);
        }

        // 如果没有设置特定权限要求，则允许访问
        if (requiredPermission == null || requiredPermission.isEmpty()) {
            return true;
        }

        // 从Spring Security上下文中获取当前认证的用户--解决401问题
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated() ||
                "anonymousUser".equals(authentication.getPrincipal())) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"success\":false,\"code\":401,\"message\":\"未登录\",\"data\":null}");
            return false;
        }

        // 从认证信息中获取用户名
        String username = authentication.getName();
        if (username == null || username.isEmpty()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"success\":false,\"code\":401,\"message\":\"未登录\",\"data\":null}");
            return false;
        }

        User user = userService.getUserByUsername(username);
        if (user == null || user.getStatus() != 1) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.getWriter().write("{\"success\":false,\"code\":403,\"message\":\"用户已被禁用或不存在\",\"data\":null}");
            return false;
        }

        // 获取请求所需的权限码
         requiredPermission = getRequiredPermission(request);

        // 如果没有设置特定权限要求，则允许访问
        if (requiredPermission == null || requiredPermission.isEmpty()) {
            return true;
        }

        // 使用新的权限检查机制
        if (!hasPermissionNew(user, requiredPermission)) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.getWriter().write("{\"success\":false,\"code\":403,\"message\":\"权限不足\",\"data\":null}");
            return false;
        }

        return true;
    }

    private String getRequiredPermission(HttpServletRequest request) {
        // 从请求头中获取所需权限码
        return request.getHeader("permission-code");
    }

    /**
     * 新的权限检查方法，使用组合模式和权限树
     * @param user 用户
     * @param permissionCode 权限代码
     * @return 是否具有权限
     */
    private boolean hasPermissionNew(User user, String permissionCode) {
        try {
            // 使用PermissionService的新方法检查权限
            return permissionService.checkUserPermission(user.getId(), permissionCode);
        } catch (Exception e) {
            // 如果新方法出错，回退到旧方法
            return user.getRoles().stream()
                    .flatMap(role -> role.getPermissions().stream())
                    .anyMatch(permission -> permissionCode.equals(permission.getPermissionCode()));
        }
    }
}